import os
import shutil
import cv2
import time
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
data_path = "./data"
train_path = "./train/"
test_path = "./test/"
train_files = [ f for f in os.listdir("train") if not f.startswith('.')]
test_files = [ f for f in os.listdir("test") if not f.startswith('.')]
print(len(train_files),train_files[0:10])
print(len(test_files),test_files[0:10])
# 获取训练图片的大小分布图
def get_images_distribution():
images_size_list = []
images_origin = []
for image in train_files:
img = cv2.imread(train_path + "/" + image)
size = img.shape[:2]
images_size_list.append(size)
images_origin.append(img)
return images_size_list,images_origin
start = time.time()
images_size_list,images_origin = get_images_distribution()
print(time.time() - start)
# 作出训练数据的分布图
xb = [ t[0] for t in images_size_list]
yb = [ t[1] for t in images_size_list]
plt.scatter(xb,yb)
plt.title('Image Size Scatter Plot')
plt.xlabel('image width in pixel')
plt.ylabel('image height in pixel')
print("width means value is :", np.mean(xb))
print("width min value is :", np.min(xb))
print("width max value is :", np.max(xb))
print("width median value is :", np.median(xb))
print("height means value is :", np.mean(yb))
print("height min value is :", np.min(yb))
print("height max value is :", np.max(yb))
print("height median value is :", np.median(yb))
print("width variance is:", np.var(xb),", height variance is: ",np.var(yb))
print("width std is:", np.std(xb),", height std is: ",np.std(yb))
import random
random.seed(2018)
plt.figure(figsize=(16, 8))
for i in range(8):
plt.subplot(241+i)
plt.imshow(images_origin[random.randint(0,len(train_files))])
plt.axis('off')
plt.show()
训练图片
random.seed(2018)
plt.figure(figsize=(16, 8))
for i in range(8):
plt.subplot(241+i)
r = random.randint(0,len(train_files))
plt.imshow(images_origin[r])
plt.title(train_files[r])
# plt.axis('off')
plt.show()
测试图片
random.seed(2018)
plt.figure(figsize=(16, 8))
for i in range(8):
plt.subplot(241+i)
r = random.randint(0,len(test_files))
img = cv2.imread(test_path + "/" + test_files[r])
plt.imshow(img)
plt.title(test_files[r])
# plt.axis('off')
plt.show()
from sklearn.model_selection import train_test_split
# 切分训练数据
img_train, img_cv = train_test_split(train_files, test_size=0.2, random_state=32)
print(len(img_train), len(img_cv))
从训练文件中分出猫和狗的图片,将其在 data 目录中分别存储到 train 和 valid 下。
# 创建所需要的目录
def mkdir_img():
train_root = data_path + "/train"
valid_root = data_path + "/valid"
test_root = data_path + "/test"
train_cats = train_root + "/cats/"
train_dogs = train_root + "/dogs/"
valid_cats = valid_root + "/cats/"
valid_dogs = valid_root + "/dogs/"
test_sub = test_root + "/test/"
if os.path.exists(train_root):
shutil.rmtree(train_root)
if os.path.exists(valid_root):
shutil.rmtree(valid_root)
if os.path.exists(test_root):
shutil.rmtree(test_root)
os.mkdir(train_root)
os.mkdir(valid_root)
os.mkdir(train_cats)
os.mkdir(train_dogs)
os.mkdir(valid_cats)
os.mkdir(valid_dogs)
os.mkdir(test_root)
os.mkdir(test_sub)
# 将训练数据与验证数据分目录
def separate_imgs():
# 训练数据
for img in img_train:
if "cat" in img:
shutil.copyfile(train_path + img, data_path + "/train/cats/" + img )
if "dog" in img:
shutil.copyfile(train_path + img, data_path + "/train/dogs/" + img )
# 验证数据
for img in img_cv:
if "cat" in img:
shutil.copyfile(train_path + img, data_path + "/valid/cats/" + img )
if "dog" in img:
shutil.copyfile(train_path + img, data_path + "/valid/dogs/" + img )
# 测试数据
for img in test_files:
shutil.copyfile(test_path + img, data_path + "/test/test/" + img )
start = time.time()
mkdir_img()
separate_imgs()
print(time.time() - start)
from keras.models import *
from keras.layers import *
from keras.applications import *
from keras.preprocessing.image import *
from keras.callbacks import ModelCheckpoint
import h5py
# 设定 Xception 图片的大小
width,height=299,299
image_size = (width,height)
# 生成训练与验证图片
gen = ImageDataGenerator()
train_generator = gen.flow_from_directory(
'data/train',
target_size=image_size,
shuffle=False,
batch_size=16)
validation_generator = gen.flow_from_directory(
'data/valid',
target_size=image_size,
shuffle=False,
batch_size=16)
test_generator = gen.flow_from_directory("data/test", target_size=image_size, shuffle=False,
batch_size=16, class_mode=None)
此处需要较长的时间才可以完成训练
input_tensor = Input((height, width, 3))
x = input_tensor
x = Lambda(xception.preprocess_input)(x)
base_model = Xception(input_tensor=x, weights='imagenet', include_top=False)
model = Model(base_model.input, GlobalAveragePooling2D()(base_model.output))
train = model.predict_generator(train_generator)
validation = model.predict_generator(validation_generator)
test = model.predict_generator(test_generator)
with h5py.File("xceptionV5.h5") as h:
h.create_dataset("train", data=train)
h.create_dataset("label", data=train_generator.classes)
h.create_dataset("validation", data=validation)
h.create_dataset("v_label", data=validation_generator.classes)
h.create_dataset("test", data=test)
import h5py
import numpy as np
from sklearn.utils import shuffle
np.random.seed(2018)
X_train = []
X_test = []
X_val = []
with h5py.File("xceptionV5.h5", 'r') as h:
print(h['train'],"\n",h['label'],"\n",h['validation'],"\n",h['v_label'],"\n",h['test'])
X_train.append(np.array(h['train']))
X_val.append(np.array(h['validation']))
X_test.append(np.array(h['test']))
y_train = np.array(h['label'])
y_val = np.array(h['v_label'])
X_train = np.concatenate(X_train, axis=1)
X_val = np.concatenate(X_val, axis=1)
X_test = np.concatenate(X_test, axis=1)
X_train, y_train = shuffle(X_train, y_train)
from keras.models import *
from keras.layers import *
np.random.seed(2018)
input_tensor = Input(X_train.shape[1:])
x = Dropout(0.5)(input_tensor)
x = Dense(1, activation='sigmoid')(x)
model = Model(input_tensor, x)
model.compile(optimizer='adadelta',
loss='binary_crossentropy',
metrics=['accuracy'])
print(model.summary())
from graphviz import Digraph
g = Digraph('g',node_attr={'shape': 'record', 'height': '.1'})
g.node('node0','image')
g.node('node3','Xception|{input:|output:}|{(299, 299, 3)|(2048)}')
g.node('node5','Dropout|{Rate:|input:|output:}|{0.25|(6144)|(6144)}')
g.node('node6','Output|{input:|output:}|{(6144)|(1)}')
g.edge('node0','node3')
g.edge('node3','node5')
g.edge('node5','node6')
g
history = model.fit(X_train, y_train, batch_size=128, epochs=10,validation_data=(X_val,y_val))
每步时间:直接训练与特征向量提取方式的对比
dt_time = [92 for i in range(10)]
ef_time = [57, 44, 49, 45, 44, 44, 45, 47, 69, 46]
plt.figure(figsize=(10, 5))
plt.plot(dt_time, 'g', label="Direct Training")
plt.grid(True)
plt.title('Every Steps of Time')
plt.ylabel('s for Direct Training')
plt.xlabel('Epochs')
plt.legend()
ax2 = plt.twinx()
ax2.plot(ef_time, 'r', label="Extract Feature")
ax2.set_ylabel('μs for Extract Feature')
ax2.legend()
print(np.mean(ef_time))
损失与精确度
print(history.history.keys())
fig = plt.figure(figsize=(10, 7))
# 训练与验证集的损失
plt.subplot(211)
plt.plot(history.history['loss'], 'g', label="train losses")
plt.plot(history.history['val_loss'], 'r', label="val losses")
plt.grid(True)
plt.title('Training loss vs. Validation loss')
# plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
# 训练与验证的精确度
plt.subplot(212)
plt.plot(history.history['acc'], 'g', label="train accuracy")
plt.plot(history.history['val_acc'], 'r', label="validation accuracy")
plt.grid(True)
plt.title('Training Accuracy vs. Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
y_pred = model.predict(X_test, verbose=1)
y_pred = y_pred.clip(min=0.005, max=0.995)
import pandas as pd
from keras.preprocessing.image import *
df = pd.read_csv("sample_submission.csv")
for i, fname in enumerate(test_generator.filenames):
index = int(fname[fname.rfind('/')+1:fname.rfind('.')])
df.set_value(index-1, 'label', y_pred[i])
df.to_csv('submissionV5.csv', index=None)
df.head(10)
暂时没有做类似下面的图,只做了预测结果的展示。

weights = model.layers[-1].get_weights()[0]
plt.figure(figsize=(16,8))
rows = 2
columns = 4
for i, fname in enumerate(test_generator.filenames):
if i < rows * columns:
img = cv2.imread(fname)
img = cv2.resize(img, image_size)
plt.subplot(rows, columns, i+1)
plt.title('cat %.2f%%\n dog %.2f%%' % (100 - y_pred[i]*100, y_pred[i]*100))
plt.axis('off')
plt.imshow(img)
else:
break
plt.show()
! pip freeze
以下为直接训练方式的代码
# history
base_model = Xception(include_top=False, weights='imagenet')
x = GlobalAveragePooling2D(name='avg_pool')(base_model.output)
x = Dropout(0.5)(x)
x = Dense(2, activation='sigmoid', name='output')(x)
model = Model(input=base_model.input, output=x)
model.compile(loss='binary_crossentropy', optimizer='adadelta', metrics=['accuracy'])
# best_model = ModelCheckpoint("xception.h5", monitor='val_loss', verbose=0, save_best_only=True)
model.fit_generator(
train_generator,
steps_per_epoch=2048,
epochs=50,
validation_data=validation_generator,
validation_steps=1024,
callbacks=[best_model])
print(model.summary())
# 输入张量
with open('xception.json', 'w') as f:
f.write(model.to_json())
# 加载训练好的权重信息
model.load_weights('xception_best.h5')
# 读取测试文件
def get_test_image(index):
img = cv2.imread(test_path + '/%d.jpg' % index)
img = cv2.resize(img, image_size)
img.astype(np.float32)
img = img / 255.0
return img
test_num = len(test_files)
image_matrix = np.zeros((test_num, width, height, 3), dtype=np.float32)
for i in tqdm(range(test_num)):
image_matrix[i] = get_test_image(i+1)
# 使用模型进行预测
predictions = model.predict(image_matrix, verbose=1)
s = 'id,label\n'
for i, p in enumerate(predictions):
s += '%d,%f\n' % (i+1, p)
with open('submission.csv', 'w') as f:
f.write(s)
import sys
print(sys.version)
model.load_weights('xceptionV4.h5')
def get_image(index):
img = cv2.imread('./data/test/test/%d.jpg' % index)
img = cv2.resize(img, image_size)
img.astype(np.float32)
img = img / 255.0
return img
test_num = 12500
image_matrix = np.zeros((test_num, width, height, 3), dtype=np.float32)
for i in tqdm(range(test_num)):
image_matrix[i] = get_image(i+1)
predictions = model.predict(image_matrix, verbose=1)
print(predictions)
s = 'id,label\n'
for i, p in enumerate(predictions):
s += '%d,%f\n' % (i+1, p[1])
with open('xceptionV4.csv', 'w') as f:
f.write(s)
使用 epochs=10 steps_per_epoch=1024,validation_steps=512 得到 xceptionV3 的结果图
plt.figure(figsize=(10, 7))
# 训练与验证集的损失
loss = [0.7159, 0.6589, 0.6428, 0.6230, 0.6153, 0.6175, 0.6118, 0.6031, 0.6138, 0.6015]
val_loss = [5.2721, 5.2499, 4.1525, 4.1926, 4.4549, 5.3253, 6.1636, 5.0178, 5.2519, 5.9510]
plt.subplot(211)
plt.plot(loss, 'g', label="train losses")
plt.plot(val_loss, 'r', label="val losses")
plt.grid(True)
plt.title('Training loss vs. Validation loss')
# plt.xlabel('Epochs ')
plt.ylabel('Loss')
plt.legend()
# 训练与验证的精确度
acc = [0.5732, 0.6495, 0.6647, 0.6860, 0.6945, 0.6917, 0.6924, 0.7044, 0.6978, 0.7036]
val_acc = [0.5969, 0.5956, 0.5472, 0.5241, 0.4977, 0.5859, 0.5988, 0.5080, 0.5634, 0.5904]
plt.subplot(212)
plt.plot(acc, 'g', label="train accuracy")
plt.plot(val_acc, 'r', label="validation accuracy")
plt.grid(True)
plt.title('Training Accuracy vs. Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
epochs=20 steps_per_epoch=2048,validation_steps=1024,xceptionV4
plt.figure(figsize=(10, 7))
# 训练与验证集的损失
loss = [0.6781, 0.6349, 0.6212, 0.6123, 0.6098, 0.6046, 0.6016, 0.6049, 0.6056, 0.6037, \
0.6046, 0.6031, 0.6025, 0.5975, 0.6006, 0.6007, 0.6060, 0.5966, 0.6034, 0.6027]
val_loss = [4.6464, 3.6877, 5.6829, 6.9355, 5.7195, 6.2689, 7.1742, 5.3356, 6.4428, 6.7396, \
7.2194, 6.3644, 7.2723, 7.1413, 6.9712, 7.1853, 7.3284, 7.3997, 6.9977, 7.1514]
plt.subplot(211)
plt.plot(loss, 'g', label="train losses")
plt.plot(val_loss, 'r', label="val losses")
plt.grid(True)
plt.title('Training loss vs. Validation loss')
# plt.xlabel('Epochs ')
plt.ylabel('Loss')
plt.legend()
# 训练与验证的精确度
acc = [0.6225, 0.6760, 0.6870, 0.6980, 0.6994, 0.7055, 0.7052, 0.7037, 0.7031, 0.7056, 0.7059, \
0.7077, 0.7098, 0.7129, 0.7099, 0.7095, 0.7072, 0.7100, 0.7084, 0.7075]
val_acc = [0.5405, 0.5197, 0.5105, 0.5278, 0.5171, 0.5300, 0.5308, 0.5143, 0.5278, 0.5281, 0.5311, \
0.5176, 0.5307, 0.5312, 0.5283, 0.5313, 0.5322, 0.5327, 0.5309, 0.5307]
plt.subplot(212)
plt.plot(acc, 'g', label="train accuracy")
plt.plot(val_acc, 'r', label="validation accuracy")
plt.grid(True)
plt.title('Training Accuracy vs. Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()